package com.example.service.impl;

import com.example.common.Result;
import com.example.common.PageResult;
import com.example.dto.ConsumptionRecordQueryDTO;
import com.example.entity.Appointment;
import com.example.entity.ConsumptionRecord;
import com.example.entity.User;
import com.example.mapper.AppointmentMapper;
import com.example.mapper.ConsumptionRecordMapper;
import com.example.mapper.UserMapper;
import com.example.service.ConsumptionRecordService;
import com.example.util.UserContextUtil;
import com.example.vo.ConsumptionRecordVO;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * 消费记录服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ConsumptionRecordServiceImpl implements ConsumptionRecordService {
    
    private final ConsumptionRecordMapper consumptionRecordMapper;
    private final AppointmentMapper appointmentMapper;
    private final UserMapper userMapper;
    private final UserContextUtil userContextUtil;
    
    @Override
    @Transactional
    public Result<Void> createConsumptionRecord(Long appointmentId) {
        try {
            if (appointmentId == null) {
                return Result.error("预约ID不能为空");
            }
            
            // 查询预约记录
            Appointment appointment = appointmentMapper.selectById(appointmentId);
            if (appointment == null || appointment.getDeleted() == 1) {
                return Result.error("预约记录不存在");
            }
            
            // 检查是否已存在消费记录
            ConsumptionRecord existingRecord = consumptionRecordMapper.selectByAppointmentId(appointmentId);
            if (existingRecord != null) {
                return Result.error("该预约已存在消费记录");
            }
            
            // 检查是否有套餐价格
            if (appointment.getPackagePrice() == null || appointment.getPackagePrice().compareTo(BigDecimal.ZERO) <= 0) {
                return Result.error("预约没有套餐价格，无需创建消费记录");
            }
            
            // 创建消费记录
            ConsumptionRecord consumptionRecord = new ConsumptionRecord();
            consumptionRecord.setUserId(appointment.getUserId());
            consumptionRecord.setStoreManagerId(appointment.getStoreManagerId());
            consumptionRecord.setAppointmentId(appointmentId);
            consumptionRecord.setPackageId(appointment.getPackageId());
            consumptionRecord.setPackageName(appointment.getPackageName());
            consumptionRecord.setConsumeAmount(appointment.getPackagePrice());
            consumptionRecord.setPaymentMethod("BALANCE"); // 默认余额支付
            consumptionRecord.setOrderNo(generateOrderNo());
            consumptionRecord.setStatus(1); // 成功
            consumptionRecord.setRemark("预约服务消费");
            consumptionRecord.setCreateTime(LocalDateTime.now());
            consumptionRecord.setUpdateTime(LocalDateTime.now());
            consumptionRecord.setDeleted(0);
            
            int result = consumptionRecordMapper.insert(consumptionRecord);
            if (result > 0) {
                log.info("创建消费记录成功，预约ID：{}, 消费金额：{}", appointmentId, appointment.getPackagePrice());
                return Result.success();
            } else {
                return Result.error("创建消费记录失败");
            }
        } catch (Exception e) {
            log.error("创建消费记录失败", e);
            return Result.error("创建消费记录失败：" + e.getMessage());
        }
    }
    
    @Override
    public Result<ConsumptionRecordVO> getConsumptionRecordById(Long id) {
        try {
            if (id == null) {
                return Result.error("消费记录ID不能为空");
            }
            
            ConsumptionRecord record = consumptionRecordMapper.selectById(id);
            if (record == null || record.getDeleted() == 1) {
                return Result.error("消费记录不存在");
            }
            
            ConsumptionRecordVO vo = convertToVO(record);
            return Result.success(vo);
        } catch (Exception e) {
            log.error("查询消费记录失败", e);
            return Result.error("查询消费记录失败：" + e.getMessage());
        }
    }
    
    @Override
    public Result<ConsumptionRecordVO> getConsumptionRecordByOrderNo(String orderNo) {
        try {
            if (orderNo == null || orderNo.trim().isEmpty()) {
                return Result.error("订单号不能为空");
            }
            
            ConsumptionRecord record = consumptionRecordMapper.selectByOrderNo(orderNo);
            if (record == null || record.getDeleted() == 1) {
                return Result.error("消费记录不存在");
            }
            
            ConsumptionRecordVO vo = convertToVO(record);
            return Result.success(vo);
        } catch (Exception e) {
            log.error("根据订单号查询消费记录失败", e);
            return Result.error("查询消费记录失败：" + e.getMessage());
        }
    }
    
    @Override
    public Result<List<ConsumptionRecordVO>> getMyConsumptionRecords() {
        try {
            Long userId = userContextUtil.getCurrentUserId();
            if (userId == null) {
                return Result.error("用户未登录");
            }
            
            List<ConsumptionRecord> records = consumptionRecordMapper.selectByUserId(userId);
            List<ConsumptionRecordVO> vos = records.stream()
                .map(this::convertToVO)
                .sorted((a, b) -> b.getCreateTime().compareTo(a.getCreateTime()))
                .collect(java.util.stream.Collectors.toList());
            
            return Result.success(vos);
        } catch (Exception e) {
            log.error("查询我的消费记录失败", e);
            return Result.error("查询我的消费记录失败：" + e.getMessage());
        }
    }
    
    @Override
    public Result<List<ConsumptionRecordVO>> getStoreManagerIncomeRecords() {
        try {
            Long storeManagerId = userContextUtil.getCurrentUserId();
            if (storeManagerId == null) {
                return Result.error("用户未登录");
            }
            
            List<ConsumptionRecord> records = consumptionRecordMapper.selectByStoreManagerId(storeManagerId);
            List<ConsumptionRecordVO> vos = records.stream()
                .map(this::convertToVO)
                .sorted((a, b) -> b.getCreateTime().compareTo(a.getCreateTime()))
                .collect(java.util.stream.Collectors.toList());
            
            return Result.success(vos);
        } catch (Exception e) {
            log.error("查询店长收入记录失败", e);
            return Result.error("查询店长收入记录失败：" + e.getMessage());
        }
    }
    
    @Override
    public Result<PageResult<ConsumptionRecordVO>> getConsumptionRecordPage(ConsumptionRecordQueryDTO queryDTO) {
        try {
            PageHelper.startPage(queryDTO.getPage(), queryDTO.getSize());
            List<ConsumptionRecordVO> records = consumptionRecordMapper.selectVOList(queryDTO);
            PageInfo<ConsumptionRecordVO> pageInfo = new PageInfo<>(records);
            
            PageResult<ConsumptionRecordVO> result = new PageResult<>(
                queryDTO.getPage(),
                queryDTO.getSize(),
                pageInfo.getTotal(),
                records
            );
            
            return Result.success(result);
        } catch (Exception e) {
            log.error("分页查询消费记录失败", e);
            return Result.error("分页查询消费记录失败：" + e.getMessage());
        }
    }
    
    @Override
    public Result<PageResult<ConsumptionRecordVO>> getMyConsumptionRecordPage(int page, int size, ConsumptionRecordQueryDTO queryDTO) {
        try {
            Long userId = userContextUtil.getCurrentUserId();
            if (userId == null) {
                return Result.error("用户未登录");
            }
            
            queryDTO.setUserId(userId);
            queryDTO.setPage(page);
            queryDTO.setSize(size);
            
            return getConsumptionRecordPage(queryDTO);
        } catch (Exception e) {
            log.error("分页查询我的消费记录失败", e);
            return Result.error("分页查询我的消费记录失败：" + e.getMessage());
        }
    }
    
    @Override
    public Result<PageResult<ConsumptionRecordVO>> getStoreManagerIncomeRecordPage(int page, int size, ConsumptionRecordQueryDTO queryDTO) {
        try {
            Long storeManagerId = userContextUtil.getCurrentUserId();
            if (storeManagerId == null) {
                return Result.error("用户未登录");
            }
            
            queryDTO.setStoreManagerId(storeManagerId);
            queryDTO.setPage(page);
            queryDTO.setSize(size);
            
            return getConsumptionRecordPage(queryDTO);
        } catch (Exception e) {
            log.error("分页查询店长收入记录失败", e);
            return Result.error("分页查询店长收入记录失败：" + e.getMessage());
        }
    }
    
    @Override
    public Result<Map<String, Object>> getConsumptionStatistics() {
        try {
            Map<String, Object> statistics = new HashMap<>();
            
            BigDecimal totalAmount = consumptionRecordMapper.selectTodayTotalConsume();
            long totalCount = consumptionRecordMapper.selectTodayTotalCount();
            
            statistics.put("todayTotalAmount", totalAmount != null ? totalAmount : BigDecimal.ZERO);
            statistics.put("todayTotalCount", totalCount);
            
            return Result.success(statistics);
        } catch (Exception e) {
            log.error("获取消费统计信息失败", e);
            return Result.error("获取消费统计信息失败：" + e.getMessage());
        }
    }
    
    @Override
    public Result<Map<String, Object>> getMyConsumptionStatistics() {
        try {
            Long userId = userContextUtil.getCurrentUserId();
            if (userId == null) {
                return Result.error("用户未登录");
            }
            
            Map<String, Object> statistics = new HashMap<>();
            
            BigDecimal totalAmount = consumptionRecordMapper.selectTotalConsumeByUserId(userId);
            statistics.put("totalAmount", totalAmount != null ? totalAmount : BigDecimal.ZERO);
            
            return Result.success(statistics);
        } catch (Exception e) {
            log.error("获取我的消费统计信息失败", e);
            return Result.error("获取我的消费统计信息失败：" + e.getMessage());
        }
    }
    
    @Override
    public Result<Map<String, Object>> getStoreManagerIncomeStatistics() {
        try {
            Long storeManagerId = userContextUtil.getCurrentUserId();
            if (storeManagerId == null) {
                return Result.error("用户未登录");
            }
            
            Map<String, Object> statistics = new HashMap<>();
            
            BigDecimal totalAmount = consumptionRecordMapper.selectTotalIncomeByStoreManagerId(storeManagerId);
            statistics.put("totalAmount", totalAmount != null ? totalAmount : BigDecimal.ZERO);
            
            return Result.success(statistics);
        } catch (Exception e) {
            log.error("获取店长收入统计信息失败", e);
            return Result.error("获取店长收入统计信息失败：" + e.getMessage());
        }
    }
    
    @Override
    public Result<Map<String, Object>> getTodayConsumptionStatistics() {
        try {
            Map<String, Object> statistics = new HashMap<>();
            
            BigDecimal totalAmount = consumptionRecordMapper.selectTodayTotalConsume();
            long totalCount = consumptionRecordMapper.selectTodayTotalCount();
            
            statistics.put("todayTotalAmount", totalAmount != null ? totalAmount : BigDecimal.ZERO);
            statistics.put("todayTotalCount", totalCount);
            
            return Result.success(statistics);
        } catch (Exception e) {
            log.error("获取今日消费统计失败", e);
            return Result.error("获取今日消费统计失败：" + e.getMessage());
        }
    }
    
    @Override
    public Result<Map<String, Object>> getConsumptionStatisticsByDateRange(String startTime, String endTime) {
        try {
            Map<String, Object> statistics = new HashMap<>();
            
            BigDecimal totalAmount = consumptionRecordMapper.selectTotalConsumeByDateRange(startTime, endTime);
            long totalCount = consumptionRecordMapper.selectTotalCountByDateRange(startTime, endTime);
            
            statistics.put("totalAmount", totalAmount != null ? totalAmount : BigDecimal.ZERO);
            statistics.put("totalCount", totalCount);
            statistics.put("startTime", startTime);
            statistics.put("endTime", endTime);
            
            return Result.success(statistics);
        } catch (Exception e) {
            log.error("根据时间范围获取消费统计失败", e);
            return Result.error("获取消费统计失败：" + e.getMessage());
        }
    }
    
    /**
     * 生成订单号
     */
    private String generateOrderNo() {
        String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        String uuid = UUID.randomUUID().toString().replace("-", "").substring(0, 8);
        return "CONSUME" + timestamp + uuid.toUpperCase();
    }
    
    /**
     * 将实体转换为VO
     */
    private ConsumptionRecordVO convertToVO(ConsumptionRecord record) {
        ConsumptionRecordVO vo = new ConsumptionRecordVO();
        vo.setId(record.getId());
        vo.setUserId(record.getUserId());
        vo.setStoreManagerId(record.getStoreManagerId());
        vo.setAppointmentId(record.getAppointmentId());
        vo.setPackageId(record.getPackageId());
        vo.setPackageName(record.getPackageName());
        vo.setConsumeAmount(record.getConsumeAmount());
        vo.setPaymentMethod(record.getPaymentMethod());
        vo.setOrderNo(record.getOrderNo());
        vo.setStatus(record.getStatus());
        vo.setRemark(record.getRemark());
        vo.setCreateTime(record.getCreateTime());
        vo.setUpdateTime(record.getUpdateTime());
        
        // 获取用户和店长名称
        try {
            User user = userMapper.selectById(record.getUserId());
            if (user != null) {
                vo.setUsername(user.getUsername());
                vo.setNickname(user.getNickname());
            }
            
            User storeManager = userMapper.selectById(record.getStoreManagerId());
            if (storeManager != null) {
                vo.setStoreManagerName(storeManager.getNickname() != null ? storeManager.getNickname() : storeManager.getUsername());
            }
        } catch (Exception e) {
            log.warn("获取用户或店长信息失败", e);
        }
        
        return vo;
    }
} 